package com.dp.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


import com.dp.client.dto.Fecha;
import com.dp.client.dto.PaqueteDTO;
import com.dp.client.dto.PaqueteEnvio;
import com.dp.client.dto.ResultadosQuerySimulacionDTO;
import com.dp.client.dto.RutasVueloEnvio;
import com.dp.client.dto.VueloEnvio;
import com.dp.client.dto.AlmacenDTO;
import com.dp.client.servicios.simulacion.IServiciosSimulacion;
import com.dp.server.backend.PaqueteBackend;
import com.dp.server.backend.RutaDeVueloBackend;
import com.dp.server.backend.VueloBackend;
import com.dp.server.backend.servicios.ServiciosBackend;
import com.google.gson.Gson;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class IServiciosSimulacionImpl extends RemoteServiceServlet implements IServiciosSimulacion{

	@Override
	public String testSimulacion() {
		return "nada";
	}
	
	@Override
	public List < RutasVueloEnvio > obtenerRutas(PaqueteEnvio paquete) {
		PaqueteBackend pqt= new PaqueteBackend(paquete);
		ArrayList <RutasVueloEnvio> rutas = new ArrayList <> ();
		try {
			RutaDeVueloBackend[] result=new ServiciosBackend().generaRutasDevuelo(pqt);
			for (RutaDeVueloBackend r: result){
				ArrayList <VueloEnvio> vuelos= new ArrayList <>();
				for (VueloBackend v: r.vuelos){
					vuelos.add(new VueloEnvio(v.idVuelo,v.descripcion));
				}
				rutas.add(new RutasVueloEnvio (vuelos));
			}
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return rutas;
	}
	@Override
	public String correSimulacion() {
		try {
			return new ServiciosBackend().SimulacionSimple();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "No se pudo ejecutar la simulacion";
	}

	@Override
	public boolean ejecutaRuta(RutasVueloEnvio ruta, PaqueteEnvio paquete) {
		RutaDeVueloBackend rutaBackend = new RutaDeVueloBackend(ruta);
		PaqueteBackend paqueteBackend = new PaqueteBackend(paquete);
		try {
			return new ServiciosBackend().EjecutaRuta(rutaBackend, paqueteBackend);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public int getCapacidadDisponibleAlmacenEnFecha(String almacenNombre,
			java.util.Date fecha) {
		Fecha f = Fecha.getFechaFromDate(fecha);
		try {
			return new ServiciosBackend().getCapacidadDisponibleAlmacenEnFecha(almacenNombre, f);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return 0;
	}

	@Override
	public void start() {
		try {
			new ServiciosBackend().start();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void restart() {
		try {
			new ServiciosBackend().restart();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public boolean reasignarRuta(PaqueteDTO paqueteDTO){
		AlmacenDTO origen=(new IServiciosAlmacenImpl()).getAlmacen(paqueteDTO.almacenActual);
		AlmacenDTO destino=(new IServiciosAlmacenImpl()).getAlmacen(paqueteDTO.almacenDestino);
		int j=1;
		if (origen.getCiudad().getPais().getContinente().getId() !=	destino.getCiudad().getPais().getContinente().getId() )
			j=2;
		Date aux=new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime( aux );
		calendar.add( Calendar.HOUR_OF_DAY , j );
		PaqueteEnvio pqt = new PaqueteEnvio ( origen.getDescripcion() ,destino.getDescripcion() , aux , calendar.getTime() );
		
		List < RutasVueloEnvio > rutas=obtenerRutas(pqt);
		
		if (rutas.size()==0) return false;
		for (RutasVueloEnvio r:rutas){
			if ( ejecutaRuta(r, pqt ) ){
				int [] vuelos=new int [r.vuelos.size()];
				for ( int i=0 ; i < r.vuelos.size() ; i++ ){
					vuelos[ i ] = r.vuelos.get(i).idVuelo;
				}
					int pos=new IServiciosPaqueteImpl().generarPlanDeVuelo(paqueteDTO.getId(), vuelos);
					paqueteDTO.planDeVuelo=pos;
					System.out.println("pos "+pos);
					paqueteDTO.reruteo=false;
					new IServiciosPaqueteImpl().registrarPaquete(paqueteDTO);
					new IServiciosEnviarCorreo().CambioRuta(paqueteDTO.getClienteRemitente(), paqueteDTO.getClienteDestinatario(), paqueteDTO);
					return true;
				
			}
		}
		
		
		return false;
	}

	@Override
	public int crearSesionSimulacion(int minutosSesion, int dias) {
		try {
			return new ServiciosBackend().crearSesionSimulacion(minutosSesion, dias);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return -1;
	}

	@Override
	public boolean startSimulacion(int idSimulacion) {
		try {
			return new ServiciosBackend().startSimulacion(idSimulacion);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public void cambioCapacidadConexion(int idSimulacion, int idConexion,
			int nuevaCapacidad) {
		try {
			new ServiciosBackend().cambioCapacidadConexion(idSimulacion, idConexion, nuevaCapacidad);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void cambioCapacidadAlmacen(int idSimulacion, int idAlmacen,
			int nuevaCapacidad) {
		try {
			new ServiciosBackend().cambioCapacidadAlmacen(idSimulacion, idAlmacen, nuevaCapacidad);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public ResultadosQuerySimulacionDTO getResultadosDeSimulacionParaIntervaloDeTiempo(
			int idSimulacion, Fecha inicio, Fecha fin) {
		try {
			return new ServiciosBackend().getQueryWindowSimulacion(idSimulacion, inicio, fin);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
